package com.gitee.hermer.engine.jars.core.loader.event.listener;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.gitee.hermer.boot.jee.commons.verify.Assert;
import com.gitee.hermer.engine.jars.app.sdk.EngineAppClassLoader;
import com.gitee.hermer.engine.jars.core.context.IEngineAppContext;
import com.gitee.hermer.engine.jars.core.context.domain.EngineAppInfoContext;
import com.gitee.hermer.engine.jars.core.context.impl.EngineAppContextImpl.EngineAppLoaderState;
import com.gitee.hermer.engine.jars.core.event.listener.EngineEventListener;
import com.gitee.hermer.engine.jars.core.execute.EngineExecuteRunnable;
import com.gitee.hermer.engine.jars.core.execute.EngineExecuteThread.LifeCycle;
import com.gitee.hermer.engine.jars.core.execute.manage.IEngineExecutePoolManager;
import com.gitee.hermer.engine.jars.core.loader.event.EngineAppDestroyEvent;
import com.gitee.hermer.engine.jars.core.loader.release.impl.EngineAppClassLoaderReleaseHandle;

@Component
public class EngineAppDestroyEventListener extends EngineEventListener<EngineAppDestroyEvent>{

	@Autowired
	private IEngineAppContext engineAppContext;	

	@Autowired
	private IEngineExecutePoolManager executePoolManager;

	@Autowired
	private EngineAppClassLoaderReleaseHandle classLoaderReleaseHandle;

	
	
	public EngineAppInfoContext getEnableAppModelContext(String cacheKey){
		try{ return  engineAppContext.getEnableAppModelContext(cacheKey); } catch (Exception e) { return null; }
	}
	
	@Override
	public void onEvent(EngineAppDestroyEvent event) {
		try{
			Assert.isTrue(event.getAppClassLoader() != null && event.getAppClassLoader() instanceof EngineAppClassLoader);
			final EngineAppInfoContext appContext = getEnableAppModelContext(event.getCacheKey()); 
			executePoolManager.executeAsyn(new EngineExecuteRunnable(parentContext,event.getAppClassLoader(),event.getCacheKey(),LifeCycle.DESTROY) {

				@Override
				public Void onExecute() throws Throwable {
					info("开始销毁容器服务 -> 实例号[%s]",event.getCacheKey());
					try{
						engineAppContext.updateEngineAppLoaderState(cacheKey, EngineAppLoaderState.BEGIN_DESTROY);
						if(appContext != null && appContext.getDestroy() != null){
							executePoolManager.execute((EngineExecuteRunnable)appContext.getDestroy());
						}else{
							// 手动释放
							classLoaderReleaseHandle.release(this); // 释放ClassLoader
						}
					}finally{
						engineAppContext.updateEngineAppLoaderState(cacheKey, EngineAppLoaderState.END_DESTROY);
					}
					return null;
				}
			});
		}catch (Throwable e) {
			error(e.getMessage(),e);
		}
	}

}
